package com.colin.jipay.taobao_hook;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.blankj.utilcode.util.SPUtils;
import com.colin.jipay.activity.MainActivity;
import com.colin.jipay.config.ActConst;
import com.colin.jipay.utils.AbSharedUtil;
import com.colin.jipay.utils.LogUtil;
import com.colin.jipay.utils.PayHelperUtils;
import com.colin.jipay.utils.SerializableHashMap;
import com.colin.jipay.utils.StringUtils;
import com.google.myjson.ExclusionStrategy;
import com.google.myjson.FieldAttributes;
import com.google.myjson.Gson;
import com.google.myjson.GsonBuilder;
import com.lidroid.xutils.HttpUtils;
import com.lidroid.xutils.exception.HttpException;
import com.lidroid.xutils.http.RequestParams;
import com.lidroid.xutils.http.ResponseInfo;
import com.lidroid.xutils.http.callback.RequestCallBack;
import com.lidroid.xutils.http.client.HttpRequest;

import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import io.reactivex.ObservableSource;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;

import static android.content.ContentValues.TAG;
import static com.colin.jipay.activity.MainActivity.sendmsg;

/**
 * author : Colin
 * e-mail : Colin12138@gmail.com
 * qq     : 3327763437
 * date   : 2019/5/313:55 PM
 */
public class TaobaoHook {
    private ClassLoader mClassLoader;
    private boolean donext = false;
    private Map<String, Integer> idMap = new HashMap<>();
    private static Class<?> login,STfjm;
    private static HashMap mHashMap;

    public static String getTbLoginId(){
        //获取用户名
        String uid = (String) XposedHelpers.callStaticMethod(login,"getUserId");
        LogUtil.log(uid);
        Object userinfo = XposedHelpers.callMethod(XposedHelpers.callStaticMethod(STfjm,"getInstance"),"get","Global_User_Profile"+uid);
        JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(userinfo));
        String loginId = jsonObject.getString("userNick");
        return loginId;
    }

    private   <T extends View> T findViewByResName(Activity activity, String resId, String... innerResId) {
        int id = getId(resId);
        View view = activity.findViewById(id);
        if (view != null) {
            for (String rid : innerResId) {
                id = getId(rid);
                view = view.findViewById(id);
                if (view == null) break;
            }
        }
        //noinspection unchecked
        return (T) view;
    }

    private Integer getId(String resId) {
        Integer id = idMap.get(resId);
        if (id == null) {
            try {
                String[] tokens = resId.split(":");
                String[] tokens2 = tokens[1].split("/");
                Class<?> clazz = XposedHelpers.findClass(tokens[0] + ".R$" + tokens2[0], mClassLoader);
                id = XposedHelpers.getStaticIntField(clazz, tokens2[1]);
                idMap.put(resId, id);
            } catch (Throwable e) {
                LogUtil.log(e.getMessage());
            }
        }
        return id;
    }

    public void hook(final ClassLoader classLoader, final Context context){
        try{
            mClassLoader = classLoader;
            XposedHelpers.findAndHookMethod(Activity.class, "onCreate", Bundle.class, new XC_MethodHook() {
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                    super.afterHookedMethod(param);

                    XposedBridge.log("===>Taobao Activity:"+param.thisObject.getClass().getName());
                }
            });

            //获取代付二维码
            //PaycodeChannelActivity
            Class<?> payCodeClass = XposedHelpers.findClass("com.alipay.android.app.substitute.channels.PaycodeChannelActivity",classLoader);
            //FlyBirdWindowActivity
            Class<?> startHelpPayCLass = XposedHelpers.findClass("com.alipay.android.app.flybird.ui.window.FlyBirdWindowActivity",classLoader);
            Class<?> miniLaucherClass = XposedHelpers.findClass("com.alipay.android.app.pay.MiniLaucherActivity",classLoader);
            Class<?> requestClass = XposedHelpers.findClass("c8.STQCd",classLoader);
            Class<?> reqDataClass = XposedHelpers.findClass("c8.STELd",classLoader);
            Class<?> C141Class = XposedHelpers.findClass("c8.STJLd",classLoader);
            Class<?> STeDt = XposedHelpers.findClass("c8.STeDt",classLoader);
            Class<?> C1625STTki = XposedHelpers.findClass("c8.STTki",classLoader);
            final Class<?> C4615STjDt = XposedHelpers.findClass("c8.STjDt",classLoader);
            Class<?> STKvj = XposedHelpers.findClass("c8.STKvj",classLoader);
            Class<?> STyBt = XposedHelpers.findClass("c8.STyBt",classLoader);
            Class<?> STzux = XposedHelpers.findClass("c8.STzux",classLoader);
            Class<?> STCsx = XposedHelpers.findClass("c8.STCsx",classLoader);
            Class<?> STMCt = XposedHelpers.findClass("c8.STMCt",classLoader);
            Class<?> STzDt = XposedHelpers.findClass("c8.STzDt",classLoader);
            Class<?> STuvj = XposedHelpers.findClass("c8.STuvj",classLoader);
            Class<?> STvvj = XposedHelpers.findClass("c8.STvvj",classLoader);
            Class<?> STrvj = XposedHelpers.findClass("c8.STrvj",classLoader);
            Class<?> STsgk = XposedHelpers.findClass("c8.STsgk",classLoader);
            Class<?> STyvj = XposedHelpers.findClass("c8.STyvj",classLoader);
            Class<?> STNvj = XposedHelpers.findClass("c8.STNvj",classLoader);
            Class<?> STtjm = XposedHelpers.findClass("c8.STtjm",classLoader);
            Class<?> STfjm1 = XposedHelpers.findClass("c8.STfjm",classLoader);
            Class<?> login1 = XposedHelpers.findClass("com.taobao.login4android.api.Login",classLoader);
            final Class<?> STxDt = XposedHelpers.findClass("c8.STxDt",classLoader);
            Class<?> PurchaseActivity = XposedHelpers.findClass("com.taobao.tao.purchase.activity.PurchaseActivity",classLoader);
            Class<?> DetailActivity = XposedHelpers.findClass("com.taobao.tao.detail.activity.DetailActivity",classLoader);
            Class<?> MtopResponse = XposedHelpers.findClass("mtopsdk.mtop.domain.MtopResponse",classLoader);
            Class<?> BaseOutDo = XposedHelpers.findClass("mtopsdk.mtop.domain.BaseOutDo",classLoader);
            final Class<?> BuyEngine = XposedHelpers.findClass("c8.STtux",classLoader);
            Class<?> userProfileAct = XposedHelpers.findClass("com.taobao.mytaobao.setting.UserProfileActivity",classLoader);

            login = login1;
            STfjm = STfjm1;

            GsonBuilder gsonBuilder = new GsonBuilder();
            gsonBuilder.setExclusionStrategies(new ExclusionStrategy() {
                @Override
                public boolean shouldSkipField(FieldAttributes fieldAttributes) {
                    Class clz = fieldAttributes.getDeclaredClass();
                    return clz.isInterface() || clz == BuyEngine || clz == WeakReference.class;
                }

                @Override
                public boolean shouldSkipClass(Class<?> aClass) {
                    return false;
                }
            });

            XposedHelpers.findAndHookMethod(userProfileAct, "onCreate", Bundle.class,new XC_MethodHook() {
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                    super.afterHookedMethod(param);
                    Thread.sleep(1000);
//                    String recentNick = SPUtils.getInstance().getString("tbNick","-");
//                    String lastNick = getTbLoginId();
//                    if (lastNick.equals(recentNick)){
//                        Toast.makeText(context,"未检测到新的淘宝账号,操作返回!",Toast.LENGTH_LONG).show();
//                        return;
//                    }
//                    SPUtils.getInstance().put("tbNick",lastNick);
                    Intent intent = new Intent();
                    intent.setAction(ActConst.TB_NEW_NICK);
                    intent.putExtra("nick",getTbLoginId());
                    context.sendBroadcast(intent);
//                    Toast.makeText(context,"检测到新的淘宝账号,开始上传!",Toast.LENGTH_LONG).show();
                }
            });

            XposedHelpers.findAndHookConstructor(STyvj, Context.class, STCsx, int.class, new XC_MethodHook() {
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                    super.afterHookedMethod(param);
                }
            });

            XposedHelpers.findAndHookMethod(STvvj, "bind", STrvj, View.class, new XC_MethodHook() {
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                    super.afterHookedMethod(param);
                }
            });

            XposedHelpers.findAndHookMethod(STuvj, "onClick", View.class, new XC_MethodHook() {
                @Override
                protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                    super.beforeHookedMethod(param);
                    int id = ((View)param.args[0]).getId();
                }
            });

            XposedHelpers.findAndHookMethod(STzDt, "bindData", new XC_MethodHook() {
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                    super.afterHookedMethod(param);
                    if (donext){
                        Field confirm = XposedHelpers.findField(param.thisObject.getClass(),"btnConfirm");
                        Field help = XposedHelpers.findField(param.thisObject.getClass(),"btnHelpShopping");
                        Button confirmBtn = (Button) confirm.get(param.thisObject);
                        Button helpBtn = (Button) confirm.get(param.thisObject);
//                    helpBtn.performClick();
                        confirmBtn.performClick();
                        donext =false;
                    }

                }
            });

            XposedHelpers.findAndHookMethod(PurchaseActivity, "onCreate", Bundle.class, new XC_MethodHook() {
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                    super.beforeHookedMethod(param);
                    Context context1 = (Context) param.thisObject;
                    Intent intent = ((Activity)param.thisObject).getIntent();
                    Bundle bundle = intent.getExtras();
                    Set<String> bundleSet = bundle.keySet();
                    for (String key : bundleSet){
                        LogUtil.log(key+"value="+bundle.get(key));
                    }

                }
            });

            XposedHelpers.findAndHookMethod(STyBt, "initView", new XC_MethodHook() {
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                    super.afterHookedMethod(param);
                }
            });

            XposedHelpers.findAndHookMethod(PurchaseActivity, "initView", new XC_MethodHook() {
                @Override
                protected void afterHookedMethod(final MethodHookParam param) throws Throwable {
                    super.afterHookedMethod(param);

                    Activity activity = (Activity)param.thisObject;
                    final ListView listView = findViewByResName(activity, "com.taobao.taobao:id/lv_content");
                    final ViewGroup content = (ViewGroup) activity.findViewById(android.R.id.content);
                    Disposable disposable = PayHelperUtils.findTextViewByText(content, "购买数量", 10)
                            .flatMap(new Function<TextView, ObservableSource<TextView>>() {
                                @Override
                                public ObservableSource<TextView> apply(TextView textView) throws Exception {
                                    listView.setSelection(listView .getAdapter().getCount()-1);
                                    return PayHelperUtils.findTextViewByText(content, "朋友代付", 10);
                                }
                            })
                            .subscribe(new Consumer<TextView>() {
                                @Override
                                public void accept(TextView textView) throws Exception {
                                    donext = true;
                                    ViewGroup parent = (ViewGroup) textView.getParent();
                                    parent.performClick();
                                }
                            }, new Consumer<Throwable>() {
                                @Override
                                public void accept(Throwable throwable) throws Exception {
                                    LogUtil.log(throwable.getMessage());
                                }
                            });
//                    XposedHelpers.callMethod(STxDt,"onClick");
                }
            });

            //获取支付参数
            XposedHelpers.findAndHookMethod(requestClass, "requestData", reqDataClass, C141Class, new XC_MethodHook() {
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                    super.afterHookedMethod(param);
                    JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(param.getResult()));
                    JSONObject jsonObject1 = JSON.parseObject(JSON.toJSONString(param.args[0]));
                    JSONObject jsonObject2 = JSON.parseObject(JSON.toJSONString(param.args[1]));
                    LogUtil.log(jsonObject.toString());
                    LogUtil.log(jsonObject1.toString());
                    LogUtil.log(jsonObject2.toString());

                    String mspParam = jsonObject1.getJSONObject("mData").getString("mspParam")+"#";
                    String _bizNo = StringUtils.getTextCenter(mspParam,"trade_no=","#");
                    JSONObject mData = jsonObject.getJSONObject("mData");
                    JSONObject data = mData.getJSONObject("data");
                    if (null == data.getJSONObject("params").getString("codeurl")){
                        Toast.makeText(context,"已达10笔上限!",Toast.LENGTH_LONG).show();
                        return;
                    }
                    String codeurl = data.getJSONObject("params").getString("codeurl");
                    String bizNo = StringUtils.getTextCenter(codeurl,"biz_no=","_");
                    mHashMap = new HashMap();
                    mHashMap.put("codeurl",codeurl);//代付链接
                    mHashMap.put("loginId",getTbLoginId());
                }
            });

            //Hook支付弹窗
//            XposedHelpers.findAndHookMethod("android.widget.TextView", classLoader, "onAttachedToWindow",
//                    new Object[]{new XC_MethodHook() {
//                        @Override
//                        protected void afterHookedMethod(MethodHookParam param) throws Throwable {
//                            final TextView textView = (TextView)param.thisObject;
//                            String toString = textView.toString();
//                            //LogUtil.log(toString + ",text:" + textView.getText() + ", context:" + textView.getContext().toString());
//                            if(param.thisObject.getClass().getName().equals("")) {
//                                String text = textView.getText().toString();
//                                String name = "立即付款";
//                                if(text.trim().equals(name)) {
//
//                                    textView.postDelayed(new Runnable() {
//
//                                        @Override
//                                        public void run() {
//                                            ViewParent p = textView.getParent();
//                                            ((ViewGroup)p).performClick();
//                                        }
//
//                                    }, 500);
//
//                                }
//                            }else if(toString.contains(":id/spwd_input")) {
//                                //自动填充支付密码
//                                LogUtil.log("get");
//                                textView.setFocusable(true);
//                                textView.setFocusableInTouchMode(true);
//                                textView.requestFocus();
////
//                                textView.post(new Runnable() {
//                                    @Override
//                                    public void run() {
//                                        //获取支付密码
//                                        LogUtil.log("set");
//                                        textView.setText("201450");
//                                    }
//
//                                });
//                            }
//                        }
//                    }});

            XposedBridge.hookAllMethods(Intent.class, "putExtra", new XC_MethodHook() {
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                    super.afterHookedMethod(param);
                    Intent intent = (Intent) param.getResult();
                    Bundle bundle = intent.getExtras();
                    Set<String> set = bundle.keySet();
                    for (String key : set){
                       // LogUtil.log(key+"--value="+bundle.get(key));
                    }
                }
            });

            //orderDetail
            Class<?> orderDetailCore = XposedHelpers.findClass("com.taobao.order.detail.ui.OrderCoreDetailActivity",classLoader);
            XposedHelpers.findAndHookMethod(orderDetailCore, "onCreate", Bundle.class, new XC_MethodHook() {
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                    super.afterHookedMethod(param);
                    LogUtil.log("---");
                    String orderId = (String) XposedHelpers.getObjectField(param.thisObject,"mOrderId");
                    LogUtil.log(orderId);

                    Intent intent = new Intent();
                    mHashMap.put("_bizNo",orderId);//原本订单号
                    SerializableHashMap serializableHashMap = new SerializableHashMap();
                    serializableHashMap.setMap(mHashMap);
                    Bundle bundle = new Bundle();
                    bundle.putSerializable("data",serializableHashMap);
                    intent.putExtras(bundle);
                    intent.setAction("com.colin.taobao.getbiz");
                    context.sendBroadcast(intent);
                    LogUtil.log("sendcode");
                    ((Activity)param.thisObject).finish();
                }
            });

            //WEEX
            Class<?> weexAct = XposedHelpers.findClass("com.taobao.weex.WXActivity",classLoader);
            XposedHelpers.findAndHookMethod(weexAct, "onCreate", Bundle.class, new XC_MethodHook() {
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                    super.afterHookedMethod(param);
                    ((Activity)param.thisObject).finish();
                }
            });

            XposedHelpers.findAndHookMethod(miniLaucherClass, "resolveIntent", Intent.class, new XC_MethodHook() {
                @Override
                protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                    super.beforeHookedMethod(param);
                    Bundle bundle = ((Intent)param.args[0]).getExtras();
                    Set<String> bundleSet = bundle.keySet();
                    for (String key : bundleSet){
                    }
                }
            });

            XposedHelpers.findAndHookMethod(startHelpPayCLass, "onCreate", Bundle.class, new XC_MethodHook() {
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                    super.afterHookedMethod(param);
                    Bundle bundle = ((Activity)param.thisObject).getIntent().getExtras();
                    Set<String> bundelSet = bundle.keySet();
                    for (String key : bundelSet){
                    }
                }
            });

            XposedHelpers.findAndHookMethod(payCodeClass, "onCreate", Bundle.class, new XC_MethodHook() {
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                    super.beforeHookedMethod(param);
                    Intent intent = ((Activity)param.thisObject).getIntent();
                    Bundle bundle = intent.getExtras();
                    Set<String> bundleSet = bundle.keySet();
                    for (String key : bundleSet){
                        XposedBridge.log("==>"+bundle.get(key));
                    }

                }
            });
        }catch(Exception e){
            XposedBridge.log("Err==>"+e.getMessage());
        }

    }

}
